package com.Lgwd.controller.combatController;


import com.Lgwd.dao.CombatInfoDao;
import com.Lgwd.dao.DropDao;
import com.Lgwd.dao.ItemDao;
import com.Lgwd.entity.MonsterEntiy;
import com.Lgwd.entity.UserEntiy;
import com.Lgwd.repository.UserRepository;
import com.Lgwd.service.backService.DropGoodsService;
import com.Lgwd.service.monsterService.MonsterService;
import com.Lgwd.service.userService.UserService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.log4j.Log4j2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * websocket连接初始化一个bean
 * 创建的bean--
 */
// websocket连接点映射.
@ServerEndpoint(value = "/websocket/{account}")
@Component
@Log4j2

public class WebSocketServer {

    // 用来存储每个客户端对应的MyWebSocket对象.
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();
    // 用来记录sessionId和该session之间的绑定关系.
    private static Map<String, Session> map = new HashMap<>();

    private Session session;// 当前会话的session.
    private String scocketId;// id

    public String getScocketId() {
        return scocketId;
    }


    private static CombatInteface combatInteface;
    private static UserRepository userRepository;
    private static MonsterService monsterService;
    private static DropGoodsService dropGoodsService;
    private static UserService userService;

    @Autowired
    public void setUserRepository(UserRepository userRepository) {
        WebSocketServer.userRepository = userRepository;
    }

    @Autowired
    public void setMonsterRepository(MonsterService monsterService) {
        WebSocketServer.monsterService = monsterService;
    }

    @Autowired
    public void setDropGoodsService(DropGoodsService dropGoodsService) {
        WebSocketServer.dropGoodsService = dropGoodsService;
    }

    @Autowired
    public void setUserService(UserService userService) {
        WebSocketServer.userService = userService;
    }
    //  UserRepository userRepository;

    /**
     * 根据角色账号进行相关信息查询
     * 查询角色属性
     * 查询角色可预见怪物
     * 完成角色战斗数据
     * 更新经验值
     * 获取掉落物品
     * 返回战斗日志信息
     * 返回最新生命
     *
     * @param session
     * @param account
     * @throws InterruptedException
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("account") String account) throws InterruptedException {
        String scocketId;
        scocketId = UUID.randomUUID().toString();

        this.session = session;
        this.scocketId = scocketId;
        map.put(this.scocketId, this.session);
        // 加入set中.
        webSocketSet.add(this);



        boolean flag = true;
        do {
            UserEntiy userEntiy = userRepository.findByUser_account(account);

            //获取怪物信息
            MonsterEntiy monsterEntiy = monsterService.getMonsterByUserLv(userEntiy.getUser_lv());

            CombatInfoDao combatInfoDao1 = new CombatInfoDao();
            combatInfoDao1.setMonsterLv(monsterEntiy.getMonster_lv());
            combatInfoDao1.setMonsterHp(monsterEntiy.getMonster_HP());
            combatInfoDao1.setUserHp(userEntiy.getUser_HP());
            combatInfoDao1.setUserMp(userEntiy.getUser_MP());
            combatInfoDao1.setMonsterLog("");
            combatInfoDao1.setUserLog("");
            combatInfoDao1.setFlag(1);

            broadById(combatInfoDao1, scocketId);


            while (flag) {
                CombatInfoDao combatInfoDao = combatInteface.CombatInfo(userEntiy, monsterEntiy);
                combatInfoDao.setFlag(1);

                Thread.sleep(1000);

                if (combatInfoDao.getMonsterHp() <= 0) {
                    combatInfoDao.setFlag(2);
                    flag = false;

                    //掉落物品
                    DropDao dropDao = new DropDao();
                    dropDao.setLv(userEntiy.getUser_lv());
                    dropDao.setUser_account(account);
                    ItemDao itemDao = dropGoodsService.returnGoods(dropDao);
                    if (itemDao == null) {
                        combatInfoDao.setItemName("未掉落物品");
                    } else {
                        combatInfoDao.setItemName("获得：" + itemDao.getItem_name());
                    }
                    //提供经验值
                    UserEntiy userEntiy1 = new UserEntiy();
                    userEntiy1.setUser_ex(monsterEntiy.getGive_ex());
                    userEntiy1.setUser_account(userEntiy.getUser_account());
                    userEntiy1 = userService.findUserGiveUp(userEntiy1);
                    combatInfoDao.setUserEx(userEntiy1.getUser_ex());
                    combatInfoDao.setUserUpEx(userEntiy1.getUser_upex());

                    broadById(combatInfoDao, scocketId);
                    break;
                }
                broadById(combatInfoDao, scocketId);


                if (combatInfoDao.getUserHp() <= 0) {
                    flag = false;
                    break;
                }

            }

        } while (flag);


    }

    /**
     * 连接关闭调用的方法.
     */
    @OnClose
    public void onClose(Session session) {

        // 从set中移除.
        webSocketSet.remove(this);
        map.remove(this.scocketId);


    }

    /**
     * 收到客户端消息后调用的方法.
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("message:" + message);
        log.info("session:" + session);
    }

    /**
     * 发生错误时调用.
     */
    public void onError(Session session, Throwable error) {
        log.error("webscoket发生错误" + error.getMessage());
    }

    /**
     * 单发
     *
     * @param socketMsg
     */
    public static void broadById(CombatInfoDao socketMsg, String id) {
        // 发送消息.
        Session session2 = map.get(id);
        if (session2 != null) {
            log.info("websocket sed>>>>>>>" + JSONObject.toJSONString(socketMsg));
            session2.getAsyncRemote().sendText(JSONObject.toJSONString(socketMsg));
        } else {
            log.error(
                    "websocket is not init>>>>>>>>>>>>>>>>>>>>>>>>>>"
                            + id);
        }

    }

//
//    /**
//     * 群发的方法.
//     *
//     * @param socketMsg
//     */
//    public static void broadcast(String socketMsg) {
//        for (WebSocketServer item : webSocketSet) {
//            // 发送消息.
//            item.session.getAsyncRemote().sendText(socketMsg);
//        }
//    }

//    /**
//     * 获取日志信息
//     *
//     * @param instanceId
//     * @param netZone
//     * @param ip
//     * @return
//     */
//    public static String getMessage(String instanceId, String netZone, String ip, String type) {
////        IAgentManagementService service = (IAgentManagementService) ApplicationContextUtil.getBean(IAgentManagementService.class);
////        List<Map<String,Object>> executiveLogging = service.getExecutiveLogging(instanceId, netZone, ip,type);
//
//        //return JSON.toJSONString(executiveLogging);
//
//        return "s";
//    }

//
//    /**
//     * 发送消息
//     *
//     * @param sendMap    推送的消息内容
//     * @param instanceId
//     * @param netZone
//     * @param ip
//     */
//    public static void sendMessage(String instanceId, String netZone, String ip, List<Map<String, String>> sendMap) {
//        String id = getId(instanceId, netZone, ip);
//        for (String sid : map.keySet()) {
//            if (sid.startsWith(id)) {
//                Session session = map.get(sid);
//                synchronized (WebSocketServer.class) {
//                    try {
//                        session.getBasicRemote().sendText(JSON.toJSONString(sendMap));
//                    } catch (IOException e) {
//                        log.error("发送消息失败--->" + e.getMessage());
//                    }
//                }
//            }
//        }
//    }

}
